package com.ce.framework.auth;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.ce.framework.constants.WebConstants;
import com.ce.framework.util.LogUtil;
import com.ce.framework.util.StringUtil;
import com.ce.sys.login.model.User;
import com.ce.sys.menu.view.SysMenuInfo;
import com.ce.util.DbUtil;
import com.ce.util.MenuUtil;


/**
* 创建人：andy
* 创建日期：2010-3-2
* 创建时间：下午05:27:17
* 功能描述：实现权限验证的过滤器
* ==============================================
* 修改历史
* 修改人		修改时间		修改原因
*
* ==============================================
*/
public class AuthenticationFilter implements Filter {

	protected Logger log = Logger.getLogger(this.getClass());
	private String target;
	private String pattern;
	private String noAuthUri;
	public static Authentication auth;
	private Pattern pat;

	public void destroy() {
	} 

	public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain arg2) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0; 
		String path = request.getServletPath(); //访问的路径地址,不带http的
		String fullPath = request.getRequestURL().toString(); //带http的全路径
		String queryStr = request.getQueryString(); //访问路径地址的参数
		if(StringUtil.isNotBlank(queryStr)){
			path = path + "?" + queryStr;   //将地址和参数组成实际的URL
			fullPath = fullPath + "?" + queryStr; 
		}
		request.setAttribute("REQUEST_PATH", path);
		path = request.getContextPath()+path;
		User user = User.getUser(request);
		if(pat.matcher(path).matches()){
			if(user==null){//如果用户未登录，则从COOKIE中加载SESSION信息
				CheckLoginFilter.initSessionId(request, (HttpServletResponse) response);
				user = User.getUser(request);
			}
			if(!auth.checkAuth(path,request)){
				String msg = "权限不足，您未被允许执行该操作，如需要请联系管理员设置权限！";
				response.setContentType("text/html; charset=UTF-8"); // 设置 content-type
				response.setCharacterEncoding("UTF-8");
				if(noAuthUri!=null)
					msg = "<script>location.href='"+request.getContextPath()+noAuthUri+"'</script>";
				response.getWriter().println(msg);
				return;
			}else{
				SysMenuInfo menuInfo = null;
			    menuInfo = MenuUtil.getMenuInfoByUrl(path);
				if(user!=null&&menuInfo!=null)
				    DbUtil.logUserOperate(user.getVcName(), request.getRemoteAddr(), menuInfo.getMenuName(), path, menuInfo.getMenuOptName(), StringUtil.fromArrayToStr(request.getParameterValues(WebConstants.SELECT_ITEMS_NAME), false), "");
			}
		}
        arg2.doFilter(arg0,response);
	}

	public void init(FilterConfig conf) throws ServletException {
		pattern = conf.getInitParameter("pattern");
		if(StringUtil.isBlank(pattern)){
			pattern = "/*";
		}
		pat = Pattern.compile(pattern.replace("**", ".*").replaceAll("([^\\.])\\*", "$1.*"));

		target = conf.getInitParameter("target");
		noAuthUri = conf.getInitParameter("noAuthUri");
		if(StringUtil.isBlank(target)){
			auth = new Authentication(){
				public boolean checkAuth(String path, HttpServletRequest request) {
					return false;
				}};
		}
		else{
			try {
				auth = (Authentication) this.getClass().getClassLoader().loadClass(target).newInstance();
			} catch (InstantiationException e) {
				log.error("类"+target+"中没有参数为空的构造方法",e);
			} catch (IllegalAccessException e) {
				log.error("类"+target+"不能访问！",e);
			} catch (ClassNotFoundException e) {
				log.error("找不到类"+target,e);
			}
		}
		if(pat.matcher(noAuthUri).matches()&&auth.checkAuth(noAuthUri, null)){
			LogUtil.logWarn("权限验证拦截器的权限不足转向URI["+noAuthUri+"]与权限实现类有冲突，会形成死锁，配置的URI无效，已将权限不足转向URI置空！");
			noAuthUri=null;
		}
		LogUtil.logDebug("[权限验证拦截器初始化]拦截URL规则:"+pattern);
		LogUtil.logDebug("[权限验证拦截器初始化]权限实现类:"+auth.getClass().getName());
		LogUtil.logDebug("[权限验证拦截器初始化]权限不足转向URI:"+noAuthUri);
		LogUtil.logInfo("[权限验证拦截器初始化成功]");
	}

}
